#include "esp_smartconfig.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "Drivers/wifi_drv.h"
#include "Drivers/nvs_drv.h"
#include <string.h>
#include "App/uart_data.h"

#define TAG "smartconfig"

static char g_ssid[SSID_MAX_LEN];
static char g_password[PASS_MAX_LEN];

#if NEW_RULE
static char g_UserID[8];
#endif

/**
 * @brief 配网事件处理函数
 *
 * 处理配网过程中的各种事件，包括：
 * - SC_EVENT_SCAN_DONE: 扫描完成
 * - SC_EVENT_FOUND_CHANNEL: 发现信道
 * - SC_EVENT_GOT_SSID_PSWD: 获取到 SSID 和密码
 * - SC_EVENT_SEND_ACK_DONE: 发送确认完成
 *
 * 当获取到 SSID 和密码后，会配置 WiFi 并尝试连接。
 * 支持新旧两种规则解析 SSID（通过 NEW_RULE 宏控制）。
 *
 * @param arg 事件处理函数参数
 * @param event_base 事件基类
 * @param event_id 事件 ID
 * @param event_data 事件数据
 */
static void event_handler(void *arg, esp_event_base_t event_base,
                          int32_t event_id, void *event_data)
{
    if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE)
    {
        ESP_LOGI(TAG, "SCAN_DONE");
    }
    else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL)
    {
        ESP_LOGI(TAG, "FOUD_CHANNLE");
    }
    else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD)
    {
        ESP_LOGI(TAG, "SC_GOT_SSID_PSWD");

        smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t *)event_data;
        wifi_config_t wifi_config;
        char ssid[SSID_MAX_LEN] = {0};
        char password[PASS_MAX_LEN] = {0};

#if NEW_RULE
        memcpy(ssid, evt->ssid, strlen((char *)evt->ssid) - 8);
        memcpy(g_UserID, (evt->ssid) + strlen((char *)evt->ssid) - 8, 8);
        ESP_LOGI(TAG, "OSSID:%s", evt->ssid);
#else
        memcpy(ssid, evt->ssid, strlen((char *)evt->ssid));
#endif
        memcpy(password, evt->password, strlen((char *)evt->password));
        ESP_LOGI(TAG, "SSID:%s", ssid);
        ESP_LOGI(TAG, "PASSWORD:%s", password);

        bzero(&wifi_config, sizeof(wifi_config_t));
        memcpy(wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
        memcpy(wifi_config.sta.password, password, sizeof(wifi_config.sta.password));

        wifi_config.sta.bssid_set = evt->bssid_set;
        if (wifi_config.sta.bssid_set == true)
        {
            memcpy(wifi_config.sta.bssid, evt->bssid, sizeof(wifi_config.sta.bssid));
        }

        strcpy(g_ssid, ssid);
        strcpy(g_password, password);

        ESP_ERROR_CHECK(esp_wifi_disconnect());
        ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));

        esp_wifi_connect();
    }
    else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE)
    {
        xEventGroupSetBits(WifiEventGroup, SMARTCONFIG_DONE_BIT);
        running.IsSmartConfig = false;
        ESP_LOGI(TAG,"SC_EVENT_SEND_ACK_DONE");
    }
}

/**
 * @brief 配网任务函数
 *
 * 该函数实现 ESP Touch/AirKiss 配网功能:
 * 1. 断开当前 WiFi 连接
 * 2. 启动智能配网
 * 3. 等待配网完成或超时(60s)
 * 4. 配网成功则保存 WiFi 信息到 NVS
 * 5. 配网超时则恢复 WiFi 连接
 *
 * @param parm 任务参数(未使用)
 * @return void
 */
static void SmartConfigTask(void *parm)
{
    esp_wifi_disconnect();
    EventBits_t uxBits;

    ESP_ERROR_CHECK(esp_smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS));

    smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();

    esp_smartconfig_start(&cfg);
    ESP_ERROR_CHECK(esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));    
 
    uxBits = xEventGroupWaitBits(WifiEventGroup, SMARTCONFIG_DONE_BIT, false, false, 60000 / portTICK_PERIOD_MS);

    if (uxBits & SMARTCONFIG_DONE_BIT)
    {
        
        ESP_LOGI(TAG, "smartconfig over");
        write_nvs_space(NVS_WIFI_NAMESPACE, NVS_WIFI_SSID_KEY, g_ssid);         // 将ssid写入NVS
        write_nvs_space(NVS_WIFI_NAMESPACE, NVS_WIFI_PASS_KEY, g_password);     // 将password写入NVS
        esp_smartconfig_stop();
        vTaskDelete(NULL);
    }

    ESP_LOGW(TAG,"smartconfig timeout!");
    running.IsSmartConfig = false;
    ResponseWifiStatus(WIFI_DISCONNECTED);
    esp_smartconfig_stop();
    esp_wifi_connect();
    vTaskDelete(NULL);
}

/**
 * @brief 启动 SmartConfig 配网任务
 *
 * 该函数用于启动 ESP32 的 SmartConfig 配网功能。如果当前没有运行 SmartConfig，
 * 则创建一个新的配网任务；如果已经在运行，则返回失败。
 *
 * @return esp_err_t
 *         - ESP_OK: 成功启动 SmartConfig
 *         - ESP_FAIL: SmartConfig 已在运行中
 */
esp_err_t SmartConfigStart(void)
{
    if (running.IsSmartConfig == false)
    {
        running.IsSmartConfig = true;
        xTaskCreate(SmartConfigTask, "smartconfig_task", 4096, NULL, 9, NULL);
        return ESP_OK;
    }
    else
    {        
        ESP_LOGW(TAG,"smartconfig is running");
        return ESP_FAIL;
    }
}

#if NEW_RULE
/**
 * @brief 获取配网ID
 *
 * @return 返回全局变量g_UserID存储的用户ID值
 */
char GetUserID(void)
{
    return g_UserID;
}
#endif